package net.gdface.bean.jdk.factory;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.util.Arrays;
import java.util.List;

import com.google.common.base.Function;
import com.google.common.base.Optional;
import net.gdface.bean.exception.BeanPropertyRuntimeException;
import net.gdface.bean.jdk.descriptor.FieldPropertyDescriptor;
import net.gdface.cache.FunctionCached;

/**
 * @author guyadong
 * @since 2.7.0
 */
public class FieldDescriptorFactory implements PropertyDescriptorFactory {
	private static final FunctionCached<List<?>, Optional<PropertyDescriptor>> descriptorCached = FunctionCached.of(new Function<List<?>,Optional<PropertyDescriptor>>(){

		@Override
		public Optional<PropertyDescriptor> apply(List<?> input) {
			if(input.get(0) instanceof Class  && input.get(1) instanceof String){
				PropertyDescriptor descriptor = FieldPropertyDescriptor.create(((Class<?>)input.get(0)), (String)input.get(1));
				if(null!= descriptor) {
					return  Optional.of(descriptor);
				}
			}
			return Optional.absent();
		}});
	@Override
	public PropertyDescriptor descriptorOf(Object bean, String name) throws IntrospectionException {
		try {
			if(bean != null ){
				return descriptorCached.get(Arrays.asList(bean.getClass(),name)).orNull();
			}
			return null;
		} catch (BeanPropertyRuntimeException e) {
			if(e.getCause() instanceof IntrospectionException) {
				throw (IntrospectionException)e.getCause();
			}
			throw e;
		}
	}

}
